﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SCSService
{
    
    public class CartService
    {
        /// <summary>
        /// Get Cart By ProductID and shoppingCartID (GUID)
        /// </summary>
        /// <param name="shoppingCartId"></param>
        /// <param name="product"></param>
        /// <returns></returns>
        public Cart GetCartByCartIdAndProductID(string shoppingCartId, Product product)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.CartID == shoppingCartId && p.ProductID == product.ProductID
                            select p).SingleOrDefault();
                return cart;
            }
        }

        /// <summary>
        /// Get List CartItem by shoppingCartID
        /// </summary>
        /// <param name="shoppingCartId"></param>
        /// <returns></returns>
        public List<Cart> GetListCartItemByShoppingCartID(string shoppingCartId)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.CartID == shoppingCartId
                            select p);
                return cart.ToList();
            }
        }

        /// <summary>
        /// Get Cart by recordID and shoppingCartID
        /// </summary>
        /// <param name="shoppingCartId"></param>
        /// <param name="recordID"></param>
        /// <returns></returns>
        public Cart GetCartByCartIdAndRecordID(string shoppingCartId, int recordID)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.CartID == shoppingCartId && p.RecordId == recordID
                            select p).SingleOrDefault();
                return cart;
            }
        }


        /// <summary>
        /// Get total Number Product by shoppingCartId
        /// </summary>
        /// <param name="shoppingCartID"></param>
        /// <returns></returns>
        public int GetCountCartItem(string shoppingCartID)
        {
            using (var data = new DataDataContext())
            {
                int? count = (from p in data.Carts
                              where p.CartID == shoppingCartID
                              select (int?)p.Count).Sum();

                return count ?? 0;
            }
            
        }

        /// <summary>
        /// Get total number one product in CartItem 
        /// </summary>
        /// <param name="shoppingCartID"></param>
        /// <param name="productID"></param>
        /// <returns></returns>
        public int GetCountCartItemByProductID(string shoppingCartID, int productID)
        {
            using (var data = new DataDataContext())
            {
                int? count = (from p in data.Carts
                              where p.CartID == shoppingCartID && p.ProductID==productID
                              select (int?)p.Count).Sum();

                return count ?? 0;
            }
        }

        public Discount GetDiscountByProductID(int id, int? languageID)
        {
            using (var data = new DataDataContext())
            {
                var discount = (from p in data.Products
                                join dpm in data.Discount_Product_Managers on p.ProductID equals dpm.ProductID into r0
                                from e0 in r0.DefaultIfEmpty()
                                join d in data.Discounts on e0.DiscountsID equals d.DiscountsID into r1
                                from e1 in r1.DefaultIfEmpty()
                                where (p.ProductID == id) && (e1.StartDate <= DateTime.Now) && e1.Status == 1
                                select e1);


                if (languageID != null)
                {
                    discount = discount.Where(p => p.LanguagesID == languageID);
                }
                else
                    discount = discount.Where(p => p.LanguagesID == 1);         //1 la vi-VN


                discount = (from p in discount
                            orderby p.StartDate descending
                            select p);

                if (discount.Count() > 0)
                {
                    if (discount.FirstOrDefault().EndDate != null)
                    {
                        discount = (from p in discount
                                    where p.EndDate >= DateTime.Now
                                    select p);
                    }
                }

                return discount.FirstOrDefault();
            }
        }

        /// <summary>
        /// Get Total Value of CartItem by shoppingCartID
        /// </summary>
        /// <param name="shoppingCartID"></param>
        /// <param name="languageID"></param>
        /// <returns></returns>
        public double GetTotal(string shoppingCartID, int? languageID)
        {
            using (var data = new DataDataContext())
            {
                ProductService proSvc = new ProductService();
                var cartItems = GetListCartItemByShoppingCartID(shoppingCartID);

                double? totalPrice = 0;

                foreach (var item in cartItems)
                {

                    //Lưu ý chỗ này chưa có currencyID (currencyId=null)
                    double? prices = GetCountCartItemByProductID(shoppingCartID, (int)item.ProductID) * (proSvc.GetProductPriceByProductID((int)item.ProductID, languageID, null) != null ? proSvc.GetProductPriceByProductID((int)item.ProductID, languageID, null).PriceValue : 0);
                    double? dis = 0;
                    SCSService.Discount discount = GetDiscountByProductID((int)item.ProductID, languageID);
                    if (discount != null)
                    {
                        if ((bool)discount.TypeDiscounts)
                        {
                            //percent
                            dis = prices - (prices * (int)discount.DiscountPercent / 100);
                        }
                        else
                        {
                            //value
                            dis = prices - ((int)discount.DiscountPercent);
                        }
                    }
                    totalPrice += (prices - dis);
                    //totalPrice += GetCountCartItemByProductID(shoppingCartID, (int)item.ProductID) * (proSvc.GetProduct((int)item.ProductID).PriceLast);
                }

                return totalPrice ?? 0;
            }

        }


        /// <summary>
        /// Update Total Value of Order 
        /// </summary>
        /// <param name="orderID"></param>
        /// <param name="totalValue"></param>
        public void UpdateTotalOrder(int orderID, double totalValue)
        {
            using (var data = new DataDataContext())
            {
                var order = (from p in data.Customer_Orders
                             where p.OrderID == orderID
                             select p).SingleOrDefault();
                order.Total = totalValue;
                data.SubmitChanges();
            }
        }

        /// <summary>
        /// Get Cart by RecordID
        /// </summary>
        /// <param name="recordID"></param>
        /// <returns></returns>
        public Cart GetCartByRecordID(int recordID)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.RecordId == recordID
                            select p).SingleOrDefault();
                return cart;
            }
        }
        /// <summary>
        /// Get Cart by CartID
        /// </summary>
        /// <param name="CartID"></param>
        /// <returns></returns>
        public Cart GetCartByCartID(string CartID)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.CartID == CartID
                            select p).SingleOrDefault();
                return cart;
            }
        }

        /// <summary>
        /// Add cart to Tbl Cart
        /// </summary>
        /// <param name="cart"></param>
        /// <returns></returns>
        public int AddToCart(Cart cartItem)
        {
            using (var data = new DataDataContext())
            {
                data.Carts.InsertOnSubmit(cartItem);
                data.SubmitChanges();

                return cartItem.RecordId;
            }
        }


        /// <summary>
        /// Update count in CartItem
        /// </summary>
        /// <param name="cartItem"></param>
        public void UpdateQuantityCart(Cart cartItem)
        {
            using (var data = new DataDataContext())
            { 
                var cart=(from p in data.Carts
                              where p.RecordId== cartItem.RecordId
                              select p).SingleOrDefault();

                cart.Count=cartItem.Count;
                data.SubmitChanges();
            }
        }

        /// <summary>
        /// Update CartID when User Login
        /// </summary>
        /// <param name="cartItem"></param>
        public void UpdateCartId(Cart cartItem)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.RecordId == cartItem.RecordId
                            select p).SingleOrDefault();

                cart.CartID = cartItem.CartID;
                data.SubmitChanges();
            }
        }
        /// <summary>
        /// Update tempOrderID
        /// </summary>
        /// <param name="cartItem"></param>
        public void UpdateTempOrderIDforCart(Cart cartItem)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.RecordId == cartItem.RecordId
                            select p).SingleOrDefault();

                cart.TempOrderID = cartItem.TempOrderID;
                data.SubmitChanges();
            }
        }

        /// <summary>
        /// Delete one Item on Cart
        /// </summary>
        /// <param name="cartItem"></param>
        public void DeleteCartItem(Cart cartItem)
        {
            using (var data = new DataDataContext())
            {
                var cart = (from p in data.Carts
                            where p.RecordId == cartItem.RecordId
                            select p).SingleOrDefault();

                data.Carts.DeleteOnSubmit(cart);
                data.SubmitChanges();
            }
        }

        /// <summary>
        /// Create one OrderDetail for Order
        /// </summary>
        /// <param name="orderDetail"></param>
        /// <returns></returns>
        public int CreateOrderDetail(Order_Item orderDetail)
        {
            using (var data = new DataDataContext())
            {
                data.Order_Items.InsertOnSubmit(orderDetail);
                data.SubmitChanges();

                return orderDetail.OrderItemID;
            }
        }

        public int CreateOrderItemDetail(Order_Item_Detail detail)
        {
            using (var data = new DataDataContext())
            {
                data.Order_Item_Details.InsertOnSubmit(detail);
                data.SubmitChanges();

                return detail.OrderItemDetailID;
            }
        }

        /// <summary>
        /// Add Order to DB
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        public int AddOrder(Customer_Order order)
        {
            using (var data = new DataDataContext())
            {
                data.Customer_Orders.InsertOnSubmit(order);
                data.SubmitChanges();

                return order.OrderID;
            }
        }

        /// <summary>
        /// Get Customer Order by OrderID and CustomerID
        /// </summary>
        /// <param name="orderID"></param>
        /// <param name="cusID"></param>
        /// <returns></returns>
        public Customer_Order GetCustomerOrderByOrderIDAndCustomerID(int orderID, int cusID)
        {
            using (var data = new DataDataContext())
            {
                var order = (from p in data.Customer_Orders
                             where p.OrderID == orderID && p.CustomerID == cusID
                             select p).SingleOrDefault();
                return order;
            }
        }

        /// <summary>
        /// Add Shipment of Checkout
        /// </summary>
        /// <param name="ship"></param>
        /// <returns></returns>
        public int AddShipment(Shipment ship)
        {
            using (var data = new DataDataContext())
            {
                data.Shipments.InsertOnSubmit(ship);
                data.SubmitChanges();

                return ship.ShipmentID;
            }
        }
        /// <summary>
        /// config list method for siteGuid
        /// </summary>
        /// <param name="siteGuid"></param>
        /// <returns></returns>
        public List<Config_Payment_Method_Website> GetListPaymentMethod(int siteGuid)
        { 
            using(var data=new DataDataContext())
            {
                var list = (from p in data.Config_Payment_Method_Websites
                            where p.SiteGuid == siteGuid
                            select p);
                return list.ToList();
            }
        }
        /// <summary>
        /// Get config payment method by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Config_Payment_Method_Website GetConfigPaymentMethod(int id)
        {
            using (var data = new DataDataContext())
            {
                var conf = (from p in data.Config_Payment_Method_Websites
                            where p.MethodID==id
                            select p).FirstOrDefault();
                return conf;
            }
        }
        /// <summary>
        /// Get PaymentMethod byID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Payment_Method GetPaymentMethod(int id)
        {
            using (var data = new DataDataContext())
            {
                var method = (from p in data.Payment_Methods
                              where p.MethodID == id
                              select p).FirstOrDefault();
                return method;
            }
        }
        /// <summary>
        /// Create Invoice
        /// </summary>
        /// <param name="invoice"></param>
        /// <returns></returns>
        public long CreateInvoice(SCSService.Invoice invoice)
        {
            using (var data = new DataDataContext())
            {
                data.Invoices.InsertOnSubmit(invoice);
                data.SubmitChanges();

                return invoice.InvoiceID;
            }
        }
        /// <summary>
        /// Get Count Product in Order
        /// </summary>
        /// <param name="orderID"></param>
        /// <returns></returns>
        public int GetCountProductInOrder(int orderID)
        {
            using (var data = new DataDataContext())
            {
                int count=0;
                var list = (from p in data.Customer_Orders
                            join it in data.Order_Items on p.OrderID equals it.OrderID
                            where p.OrderID==orderID
                            select it);
                foreach(var item in list)
                {
                    count+=item.Quantity??0;
                }

                return count;
            }
        }
        /// <summary>
        /// Get Order by ID
        /// </summary>
        /// <param name="orderID"></param>
        /// <returns></returns>
        public Customer_Order GetOrderByID(int orderID)
        {
            using (var data = new DataDataContext())
            {
                var order = (from p in data.Customer_Orders
                             where p.OrderID == orderID
                             select p).FirstOrDefault();

                return order;
            }
        }

        public Order_Item GetOrderItemByProductIDandOrderID(int id,int orderID)
        {
            using (var data = new DataDataContext())
            {
                var orderItem = (from p in data.Order_Items
                                 where p.ProductID == id && p.OrderID==orderID
                                 select p).FirstOrDefault();
                return orderItem;
            }
        }
        /// <summary>
        /// Get Invoice top 1 by orderID
        /// </summary>
        /// <param name="orderID"></param>
        /// <returns></returns>
        public Invoice GetInvoiceByOrderID(int orderID)
        {
            using (var data = new DataDataContext())
            {
                var invoice = (from p in data.Invoices
                               where p.OrderID == orderID
                               select p).FirstOrDefault();
                return invoice;
            }
        }
        /// <summary>
        /// Update Invoice
        /// </summary>
        /// <param name="invoice"></param>
        public void UpdateInvoiceStatus(Invoice invoice)
        {
            using (var data = new DataDataContext())
            {
                var invoi = (from p in data.Invoices
                            where p.InvoiceID == invoice.InvoiceID
                            select p).SingleOrDefault();

                invoi.Status = invoice.Status;
                invoi.PaymentDate = invoice.PaymentDate;
                data.SubmitChanges();
            }
        }
        /// <summary>
        /// Update Order Status
        /// </summary>
        /// <param name="order"></param>
        public void UpdateOrderStatus(Customer_Order order)
        {
            using (var data = new DataDataContext())
            {
                var or = (from p in data.Customer_Orders
                             where p.OrderID == order.OrderID
                             select p).SingleOrDefault();

                or.OrderStatus = order.OrderStatus;
                data.SubmitChanges();
            }
        }
        /// <summary>
        /// Create Payment
        /// </summary>
        /// <param name="pay"></param>
        /// <returns></returns>
        public int CreatePayment(SCSService.Payment pay)
        {
            using (var data = new DataDataContext())
            {
                data.Payments.InsertOnSubmit(pay);
                data.SubmitChanges();

                return pay.PaymentID;
            }
        }
        /// <summary>
        /// Get List Product by orderID
        /// </summary>
        /// <param name="orderID"></param>
        /// <returns></returns>
        public List<Product> GetListProductByOrderID(int orderID)
        {
            using (var data = new DataDataContext())
            {
                var list = (from p in data.Order_Items
                            join pr in data.Products on p.ProductID equals pr.ProductID
                            where p.OrderID == orderID
                            select pr).ToList();
                return list;
            }
        }
        /// <summary>
        /// Get List Stock_Detail by OrderItem
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<Product_Stock_Detail> GetListStockDetailByOrderItem(int id)
        {
            using (var data = new DataDataContext())
            {
                var list = (from p in data.Order_Item_Details
                            join s in data.Product_Stock_Details on p.ProductStockDetailID equals s.ProductStockDetailID
                            where p.OrderItemID == id
                            select s);
                return list.ToList();
            }
        }

        /// <summary>
        /// Get Customer by userID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Customer GetCustomerByUserID(int id)
        {
            using (var data = new DataDataContext())
            {
                var cus = (from p in data.Customers
                           where p.UserID == id
                           select p);
                return cus.FirstOrDefault();
            }
        }
    }
}
